/**
 * 敏感内容检测工具
 * 提供共享的敏感内容检测函数，避免循环依赖
 */
const logger = require('./logger');

/**
 * 检查是否为信用卡号 (使用Luhn算法)
 * @param {string} number 待检查的数字串
 * @returns {boolean} 是否为有效的信用卡号
 */
const isValidCreditCard = (number) => {
  if (!number || typeof number !== 'string') return false;
  
  // 移除非数字字符
  const digits = number.replace(/\D/g, '');
  
  // 大多数信用卡号长度在13-19之间
  if (digits.length < 13 || digits.length > 19) return false;
  
  // Luhn算法检查
  let sum = 0;
  let alternate = false;
  
  for (let i = digits.length - 1; i >= 0; i--) {
    let n = parseInt(digits.charAt(i), 10);
    
    if (alternate) {
      n *= 2;
      if (n > 9) n -= 9;
    }
    
    sum += n;
    alternate = !alternate;
  }
  
  return (sum % 10 === 0);
};

/**
 * 检测敏感数字
 * @param {string} text 待检查的文本
 * @param {object} settings 检测设置
 * @returns {object} 检测结果 { isSensitive, type, matches }
 */
const detectSensitiveNumbers = (text, settings) => {
  if (!text) return { isSensitive: false };
  
  // 如果禁用了长数字串检测，返回false
  if (!settings.enableLongNumberDetection) {
    return { isSensitive: false };
  }
  
  const result = {
    isSensitive: false,
    type: null,
    matches: []
  };
  
  // 检测信用卡号
  if (settings.detectCreditCards) {
    // 找出可能的信用卡号
    const cardPattern = /\b(?:\d[ -]*?){13,19}\b/g;
    const possibleCards = text.match(cardPattern);
    
    if (possibleCards) {
      for (const card of possibleCards) {
        // 移除空格和连字符
        const cleanCard = card.replace(/[ -]/g, '');
        
        if (isValidCreditCard(cleanCard)) {
          result.isSensitive = true;
          result.type = 'creditCard';
          result.matches.push(card);
        }
      }
    }
  }
  
  // 如果已经找到敏感信息，直接返回
  if (result.isSensitive) return result;
  
  // 检测电话号码
  if (settings.detectPhoneNumbers) {
    // 匹配常见电话号码格式
    const phonePatterns = [
      /\b\d{3}[-.\s]?\d{3,4}[-.\s]?\d{4}\b/g, // 常规格式 xxx-xxxx-xxxx 或 xxx xxxx xxxx
      /\b\+\d{1,3}[-.\s]?\d{1,3}[-.\s]?\d{3,4}[-.\s]?\d{4}\b/g // 国际格式 +xx-xxx-xxxx-xxxx
    ];
    
    for (const pattern of phonePatterns) {
      const matches = text.match(pattern);
      if (matches) {
        result.isSensitive = true;
        result.type = 'phoneNumber';
        result.matches.push(...matches);
        break;
      }
    }
  }
  
  // 如果已经找到敏感信息，直接返回
  if (result.isSensitive) return result;
  
  // 检测长数字串
  const longNumberPattern = new RegExp(`\\b\\d{${settings.longNumberThreshold},}\\b`, 'g');
  const longNumbers = text.match(longNumberPattern);
  
  if (longNumbers) {
    result.isSensitive = true;
    result.type = 'longNumber';
    result.matches.push(...longNumbers);
  }
  
  // 检测自定义数字模式
  if (settings.numberPatterns && settings.numberPatterns.length > 0) {
    for (const patternStr of settings.numberPatterns) {
      try {
        const regex = new RegExp(patternStr, 'g');
        const matches = text.match(regex);
        
        if (matches) {
          result.isSensitive = true;
          result.type = 'customPattern';
          result.matches.push(...matches);
          break;
        }
      } catch (error) {
        logger.error(`无效的正则表达式: ${patternStr}`, error);
      }
    }
  }
  
  return result;
};

/**
 * 检测敏感关键词
 * @param {string} text 待检查的文本
 * @param {string[]} sensitiveKeywords 敏感关键词列表
 * @returns {object} 检测结果 { isSensitive, matches }
 */
const detectSensitiveKeywords = (text, sensitiveKeywords) => {
  if (!text) return { isSensitive: false };
  
  const result = {
    isSensitive: false,
    matches: []
  };
  
  if (!sensitiveKeywords || sensitiveKeywords.length === 0) {
    return result;
  }
  
  // 转为小写进行不区分大小写匹配
  const lowerText = text.toLowerCase();
  
  for (const keyword of sensitiveKeywords) {
    const lowerKeyword = keyword.toLowerCase();
    if (lowerText.includes(lowerKeyword)) {
      result.isSensitive = true;
      result.matches.push(keyword);
    }
  }
  
  return result;
};

/**
 * 检测文本中的所有敏感内容
 * @param {string} text 要检查的文本
 * @param {object} settings 检测设置
 * @returns {object} 检测结果
 */
const detectSensitiveContent = (text, settings) => {
  if (!text) return { hasSensitiveContent: false };
  
  const numberDetection = detectSensitiveNumbers(text, settings);
  const keywordDetection = detectSensitiveKeywords(text, settings.sensitiveKeywords);
  
  const result = {
    hasSensitiveContent: numberDetection.isSensitive || keywordDetection.isSensitive,
    numberDetection,
    keywordDetection
  };
  
  return result;
};

/**
 * 过滤敏感内容
 * @param {string} text 原始文本
 * @param {object} settings 过滤设置
 * @returns {object} 过滤结果 { filteredText, hasSensitiveContent }
 */
const filterSensitiveContent = (text, settings) => {
  if (!text) return { filteredText: '', hasSensitiveContent: false };
  
  const detection = detectSensitiveContent(text, settings);
  let filteredText = text;
  
  if (detection.hasSensitiveContent) {
    // 替换敏感数字
    if (detection.numberDetection.isSensitive && detection.numberDetection.matches.length > 0) {
      for (const match of detection.numberDetection.matches) {
        filteredText = filteredText.replace(match, '*** 敏感数字 ***');
      }
    }
    
    // 替换敏感关键词
    if (detection.keywordDetection.isSensitive && detection.keywordDetection.matches.length > 0) {
      for (const match of detection.keywordDetection.matches) {
        // 使用正则表达式进行不区分大小写的替换
        const regex = new RegExp(match, 'gi');
        filteredText = filteredText.replace(regex, '*** 敏感内容 ***');
      }
    }
  }
  
  return {
    filteredText,
    hasSensitiveContent: detection.hasSensitiveContent,
    originalText: settings.storeOriginalContent ? text : null
  };
};

module.exports = {
  isValidCreditCard,
  detectSensitiveNumbers,
  detectSensitiveKeywords,
  detectSensitiveContent,
  filterSensitiveContent
}; 